//
//  RSWebSocketManager.swift
//  ChatDemo
//
//  Created by 范强伟 on 2024/5/10.
//

import UIKit
 

class RSWebSocketManager: NSObject {

    let shareInstance = RSWebSocketManager()
    
    let urlString = "ws://pie"
    
    var webSocket: SRWebSocket?
    
    var headerBeatTimer: Timer?
    
    /// 心跳包
    var headerTime: TimeInterval = 90
    
    override init() {
        super.init()
        
    }
    
    //MARK: 连接Socket
    func collectSocket(){
        closeSocket()
        guard let url = URL(string: urlString) else { return  }
        webSocket = SRWebSocket(url: url)
        webSocket?.delegate = self
        DispatchQueue.global().async { [weak self]  in
            guard let weakself = self else { return }
            weakself.webSocket?.open()
        }
        
        initHeartBeat()
    }
    
    
    
    //MARK: 初始化心跳
    func initHeartBeat(){
        
        if let timer = headerBeatTimer{
            
        }else{
            destoryHeartBeat()
            
            DispatchQueue.main.async { [weak self]  in
                guard let weakself = self else { return }
                let time =  Timer(timeInterval: 10, target: weakself.headerTime, selector: #selector(weakself.sendHeartBeat), userInfo: nil, repeats: true)
                weakself.headerBeatTimer = time
                RunLoop.current.add(time, forMode: .common)
            }
            
        }
    }
    
    // MARK: 取消心跳
    func destoryHeartBeat(){
        DispatchQueue.main.async { [weak self] in
            guard let weakself = self else { return }
            weakself.headerBeatTimer?.invalidate()
            weakself.headerBeatTimer = nil
        }
    }
    
    /// 关闭Socket
    func closeSocket(){
        if let socket = webSocket{
            webSocket?.delegate = nil
            webSocket = nil
            webSocket?.close()
        }
    }
    
}

extension RSWebSocketManager{
    //  MARK: 取消心跳发送心跳包
    @objc func sendHeartBeat(){
        DispatchQueue.main.async { [weak self] in
            guard let weakself = self else { return }
            if let webSocket = weakself.webSocket{
                switch webSocket.readyState{
                case .CONNECTING:
                    DebugPrint("正在连接中。。。请稍后")
                    break
                case .OPEN:
                    weakself.sendPing()
                    break
                case .CLOSING:
                    // 重新连接
                    // 注意： 先关闭连接
                    // 再进行重连
                    weakself.collectSocket()
                    // 可以设置重连时间间隔限制，和重连次数限制
                    // 连接成功后 继续发送数据
                    break
                case .CLOSED:
                    // 重新连接
                    // 注意： 先关闭连接
                    // 再进行重连
                    weakself.collectSocket()
                    // 可以设置重连时间间隔限制，和重连次数限制
                    // 连接成功后 继续发送数据
                    break
                @unknown default:
                    break
                }
            }
        }
        
    }
    
    //    MARK: 发送心跳
    func sendPing(){
        do{
            let data = Data.init(base64Encoded: "heart", options: Data.Base64DecodingOptions(rawValue: NSUTF8StringEncoding))
            try webSocket!.sendPing(data as Data?)
        }
        catch{
            DebugPrint(error)
        }
    }
    
    
    
    //MARK: 发送消息
    func sendDataToServer(data: String){
        
        if let webSocket = webSocket{
            switch webSocket.readyState{
            case .CONNECTING:
                DebugPrint("正在连接中。。。请稍后")
                break
            case .OPEN:
                do{
                    try webSocket.send(string: data)
                }
                catch{
                    DebugPrint(error)
                }
                break
            case .CLOSING:
                collectSocket()
                break
            case .CLOSED:
                collectSocket()
                break
            @unknown default:
                break
            }
            
        }else{
            collectSocket()
        }
        
    }
}

extension RSWebSocketManager: SRWebSocketDelegate{
    // websocket连接成功的监听回调
    func webSocketDidOpen(_ webSocket: SRWebSocket) {
        DebugPrint("连接成功")
    }
    // 发生错误的监听回调
    func webSocket(_ webSocket: SRWebSocket, didFailWithError error: any Error) {
        DebugPrint("连接失败\(error)")
         
        DispatchQueue.main.asyncAfter(deadline: .now() + 2){ [weak self] in
            guard let weakself = self else { return }
            weakself.collectSocket()
        }
    }
    // websocket关闭的监听回调
    func webSocket(_ webSocket: SRWebSocket, didCloseWithCode code: Int, reason: String?, wasClean: Bool) {
        self.webSocket = nil
        DebugPrint("连接关闭\(reason ?? "")")
    }
    
    
    // MARK: webSocket接收消息
   
    func webSocket(_ webSocket: SRWebSocket, didReceivePingWith data: Data?) {
        
    }
    
    func webSocket(_ webSocket: SRWebSocket, didReceiveMessageWith string: String) {
        DebugPrint("接收到消息string:\(string)")
        guard let messageData = string.data(using: .utf8) else { return }
        do{
            let messageDic = try JSONSerialization.jsonObject(with: messageData)
            DebugPrint(messageDic)
        }catch{
            DebugPrint("解析失败：\(error)")
        }
        
    }
    
    func webSocket(_ webSocket: SRWebSocket, didReceiveMessageWith data: Data) {
        DebugPrint("接收到消息data:\(data)")
       
        do{
            let messageDic = try JSONSerialization.jsonObject(with: data)
            DebugPrint(messageDic)
        }catch{
            DebugPrint("解析失败：\(error)")
        }
    }
    
    func webSocket(_ webSocket: SRWebSocket, didReceivePong pongData: Data?) {
        
    }
    
    
}
